import Stack from './Stack';
import DataStore from './DataStore';

/*
    按键
        1. 按下前进, 未松开
        2. 按两下前进, 第二下未松开
        3. 左右前+a, 全部松开
*/
class Handle {
    constructor(keybord) {
        this.dataStore = DataStore.getInstance();
        this.gameConf = this.dataStore.get('gameConf');
        this.keyMap = this.gameConf[keybord];
        this.stack = new Stack(); // 记录按键, 处理连招
        this.keybordMap = new Map(); // 记录手柄操作
        for (const keyCode in this.keyMap) {
            this.keybordMap.set(this.keyMap[keyCode], {
                keyCode,
                instruction: this.keyMap[keyCode]
            })
        }
        this.keybord = keybord
        this.isDown = {};
        this.init();
        this.dataStore.get('keybordList').push(this)
    }

    init() {
        // 按下,弹起 这是一个动作
            // 按下: 动作做一次
            // 弹起
        window.addEventListener('keydown', (e) => {
            this.pushKeyBordAction({
                time: Date.now(),
                type: 'keydown',
                instruction : this.gameConf[this.keybord][e.keyCode],
                keyCode: e.keyCode,
            })
            e.preventDefault();
            e.stopPropagation();
        }, false)
        window.addEventListener('keyup', (e) => {
            this.pushKeyBordAction({
                time: Date.now(),
                type: 'keyup',
                instruction : this.gameConf[this.keybord][e.keyCode],
                keyCode: e.keyCode
            })
            e.preventDefault();
            e.stopPropagation();
        }, false)
    }
    /*
        大招，连招
        下蹲

        碰撞
    */
    getCombo() {
        // this.stack.list
        // 拼接出键位码
        let s = ''
        const { list } = this.stack
        for (let keyItem of list) {
            s += `${keyItem.instruction}: ${keyItem.type},`
        }
        return s;
    }
    // 连续的按键
    KeyStackToString(index) {
        let str = '';
        if (this.stack.list.length >= index) {
            for (let i = 0; i < index; i++) {
                const data = this.stack.list[i];
                str += `${data.instruction}: ${data.type},`;
            }
        }
        return str;
    }
    // 处理键盘事件
    pushKeyBordAction(data) {
        const { continuityFrame } = this.gameConf
        // 限制长按
        if (data.type === 'keyup') {
            this.isDown[data.keyCode] = false
        }
        if (data.type === 'keydown') {
            if (this.isDown[data.keyCode] === true) {
                return;
            }
            this.isDown[data.keyCode] = true;
        }
        if (this.keyMap[data.keyCode]) {
            // 更改手柄状态
            this.keybordMap.set(
                this.keyMap[data.keyCode],
                data
            )
            let action = this.stack.top();
            if (action && action.time) {
                if (data.time - action.time > continuityFrame &&
                    (
                        action.type !== 'keydown' ||
                        data.type !== 'keydown' 
                    )
                ) {
                    this.stack.clear();
                }
            }
            // 按键入栈: 必须是手柄上定义过的按键
            this.stack.put(data);
            if (this.stack.size() > 40) {
                this.stack.pop();
            }
        }
    }
    // 重置手柄
    reset() {
        this.stack.clear();
        for (const [o, v] of this.keybordMap) {
            v.type === 'keyup'
            this.keybordMap.set(o, {
                ...v,
                type: 'keyup'
            })
        }
    }
}

export default Handle;
